package com.app.samba.util;

import android.text.TextUtils;

import com.app.samba.DebugLog;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
import jcifs.smb.SmbFileOutputStream;

/**
 * Created Date 2019/6/14
 *
 * @author liangkun
 * description：samba协议下的读写工具类
 */
public class SambaUtil {

    /**
     * 无权限----单个文件下载
     * 从samba服务器上下载指定的文件到本地目录
     *
     * @param remoteSmbFile Samba服务器远程文件
     * @param localDir      本地目录的路径
     * @throws SmbException
     */

    public static void downloadFileFromSamba(SmbFile remoteSmbFile, String localDir) throws SmbException {

        if (!remoteSmbFile.exists()) {
            DebugLog.d(DebugLog.SAMBA_LOG + "Samba服务器远程文件不存在");
            return;
        }
        if (TextUtils.isEmpty(localDir)) {
            DebugLog.d(DebugLog.SAMBA_LOG + "本地目录路径不可以为空");
            return;
        }
        InputStream in = null;
        OutputStream out = null;

        try {
            //获取远程文件的文件名,这个的目的是为了在本地的目录下创建一个同名文件
            String remoteSmbFileName = remoteSmbFile.getName();
            //本地文件由本地目录，路径分隔符，文件名拼接而成
            File localFile = new File(localDir + File.separator + remoteSmbFileName);
            // 如果路径不存在,则创建
            File parentFile = localFile.getParentFile();
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            //打开文件输入流，指向远程的smb服务器上的文件，特别注意，这里流包装器包装了SmbFileInputStream
            in = new BufferedInputStream(new SmbFileInputStream(remoteSmbFile));
            //打开文件输出流，指向新创建的本地文件，作为最终复制到的目的地
            out = new BufferedOutputStream(new FileOutputStream(localFile));
            //缓冲内存
            byte[] buffer = new byte[1024];
            while (in.read(buffer) != -1) {
                out.write(buffer);
                buffer = new byte[1024];
            }
        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /****
     * 方法说明:无权限sambaURL方式上传单个文件
     *
     * @param source
     *            <br>
     *            参数:需要上传的源文件
     * @param remoteSmbFile
     *            <br>
     *            参数:sambaURL路径
     * @throws Exception
     *             <br>
     *             异常:文件传输过程中遇到的异常问题
     */
    public static void uploadFileToSamba(String source, SmbFile remoteSmbFile) throws Exception {
        //检查远程父路径，不存在则创建
//        SmbFile remoteSmbFile = new SmbFile(sambaURL);
        //入参检查
        if (!remoteSmbFile.exists()) {
            DebugLog.d(DebugLog.SAMBA_LOG + "Samba服务器远程目录路径不可以为空");
            return;
        }

        //入参检查
        if (TextUtils.isEmpty(source)) {
            DebugLog.d(DebugLog.SAMBA_LOG + "本地文件路径不可以为空");
            return;
        }

        InputStream in = null;
        OutputStream out = null;

        try {
            //创建一个本地文件对象
            File localFile = new File(source);
            //获取本地文件的文件名，这个名字用于在远程的Samba服务器上指定目录创建同名文件
            String localFileName = localFile.getName();

            //创建远程服务器上Samba文件对象
            SmbFile updateSmbFile = new SmbFile(remoteSmbFile.getPath() + File.separator + localFileName);
            //打开一个文件输入流执行本地文件，要从它读取内容
            in = new BufferedInputStream(new FileInputStream(localFile));

            //打开一个远程Samba文件输出流，作为复制到的目的地
            out = new BufferedOutputStream(new SmbFileOutputStream(updateSmbFile));

            //缓冲内存
            byte[] buffer = new byte[1024];
            while (in.read(buffer) != -1) {
                out.write(buffer);
                buffer = new byte[1024];
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    /**
     * 有权限---上传本地文件到Samba服务器指定目录
     *
     * @param url           samba远程url
     * @param auth          授权
     * @param localFilePath 本地文件路径
     * @throws MalformedURLException
     * @throws SmbException
     */
    public static void uploadFileToSamba(String url, NtlmPasswordAuthentication auth, String localFilePath) throws MalformedURLException, SmbException {
        //检查远程父路径，不存在则创建
        SmbFile remoteSmbFile = new SmbFile(url, auth);
        DebugLog.d(DebugLog.SAMBA_LOG + " exists " + remoteSmbFile.exists());
        //判断远程目录是否存在
        if (!remoteSmbFile.exists()) {
            remoteSmbFile.mkdirs();
        }
        if ((localFilePath == null) || ("".equals(localFilePath.trim()))) {
            DebugLog.d(DebugLog.SAMBA_LOG + "本地文件路径不可以为空");
            return;
        }
        InputStream in = null;
        OutputStream out = null;
        SmbFile updateSmbFile = null;
        try {
            File localFile = new File(localFilePath);
            updateSmbFile = new SmbFile(url + File.separator + localFile.getName(), auth);
            //打开一个文件输入流执行本地文件，要从它读取内容
            in = new BufferedInputStream(new FileInputStream(localFile));
            //打开一个远程Samba文件输出流，作为复制到的目的地
            out = new BufferedOutputStream(new SmbFileOutputStream(updateSmbFile, true));
            //缓冲内存
            byte[] buffer = new byte[1024];
            while (in.read(buffer) != -1) {
                out.write(buffer);
                buffer = new byte[1024];
            }
        } catch (Exception e) {
            if (updateSmbFile != null) {
                if (updateSmbFile.exists()) {
                    DebugLog.d(DebugLog.SAMBA_DOWN_UP + " 线程中断，删除未上传的文件------ ");
                    updateSmbFile.delete();
                }
            }
            e.printStackTrace();

        } finally {
            DebugLog.d(DebugLog.SAMBA_LOG + " uploadFileToSamba上传完成------ ");
            try {

                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 方法说明:获取samba目录中的所有文件信息
     *
     * @param username <br>
     *                 参数:用户名[匿名null]
     * @param password <br>
     *                 参数:密码[匿名null]
     * @param host     <br>
     *                 参数:samba主机或IP地址
     * @param path     <br>
     *                 参数:samba上需要获取信息的路径
     * @return 返回:List<br>
     * K-path:文件所在samba路径<br>
     * @throws MalformedURLException 异常
     * @throws SmbException          异常
     */
    public static List<Map<String, Object>> sambaFileListInfo(String username, String password, String host, String path)
            throws MalformedURLException, SmbException {
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(host, username, password);
        String remoutUrl = "smb://" + host + path;
        // 获取samba上的文件信息
        SmbFile sf = new SmbFile(remoutUrl, auth);
        // 获取文件列表
        SmbFile[] sfs = sf.listFiles();
        // 创建一个map的list集合,用于返回数据
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map;
        for (SmbFile f : sfs) {
            if (f.isDirectory()) {
                // path
                List<Map<String, Object>> ls = sambaFileListInfo(username, password, host, f.getPath());
                list.addAll(ls);
            } else {

                map = new HashMap<String, Object>();
                map.put("name", f.getName());
                map.put("lastModified", f.getLastModified());
                map.put("path", f.getPath());
                list.add(map);
            }

        }
        return list;
    }

    /**
     * 通过sambaURL方式获取目录下文件信息
     *
     * @param sambaURL 参数
     * @return 返回:
     * @throws MalformedURLException
     * @throws SmbException
     */
    public static List<Map<String, Object>> sambaFileListInfo(String sambaURL)
            throws MalformedURLException, SmbException {
        // 获取samba上的文件信息
        SmbFile sf = new SmbFile(sambaURL);
        // 获取文件列表
        SmbFile[] sfs = sf.listFiles();
        // 创建一个map的list集合,用于返回数据
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> map;
        for (SmbFile f : sfs) {
            if (f.isDirectory()) {
                // path
                List<Map<String, Object>> ls = sambaFileListInfo(f.getPath());
                list.addAll(ls);
            } else {
                map = new HashMap<String, Object>();
                map.put("name", f.getName());
                map.put("lastModified", f.getLastModified());
                map.put("path", f.getPath());
                list.add(map);
            }

        }
        return list;
    }

}
